hook = {}
hooksTable = {}
fontsTable = {}

game = {}
	game.players = {}
	game.playercount = 0
	game.hasFocus = true
	game.isPaused = false
	game.canTogglePause = false
	game.isDrawing = false

level = {}
	level.curBaseGrid = {}
	level.maps = {}

editor = {}
	editor.tools = {}
	editor.paint = true

local function areaNotFound()
	print(" area not found ")
end

areas = {}
	areas.current = "starting"
	areas.levelEditor = areaNotFound
	areas.mainGameSingle = areaNotFound
	areas.mainGameMulti = areaNotFound
	areas.optionsMenu =  areaNotFound
	areas.titleScreen = areaNotFound

statics = {}
dynamics = {}

function ScrW()
	return love.graphics.getWidth()
end

function ScrH()
	return love.graphics.getHeight()
end

function printTable(tbl, indent)
	if not indent then indent = 0 end

	for k, v in pairs(tbl) do
		formatting = string.rep(" ", indent) .. k .. ": "
		if type(v) == "table" then
			print(formatting)
			printTable(v, indent+1)
		else
			print(formatting .. tostring(v))
		end
	end
end

function distance(x1,y1,x2,y2)
	return math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
end

function hook.Call(funcCalled, args)
	for i, v in ipairs(hooksTable) do 
		if v[1] == funcCalled then
			local func = v[3]
			if not func then printTable(hooksTable) end
			func(args)
		end
	end
end

function hook.Remove(name)
	for i, v in ipairs(hooksTable) do
		if v[2]==name then
			table.remove(hooksTable, i)
		end
	end
end

function hook.Add(funcCalled, name, funcToRun )
	local found = false
	for i, v in ipairs(hooksTable) do 
		if v[2] == name then
			v = {funcCalled, name, funcToRun}
			found = true
		end
	end
	if not found then table.insert( hooksTable, {funcCalled, name, funcToRun} ) end
end

function hook.Exists(name)
	for i, v in ipairs(hooksTable) do 
		if v[2] == name then
			return true
		end
	end
	return false
end


function math.limit(num, min, max)
	if num < min then
		num = min
	elseif num > max then
		num = max
	end
	return num
end

function math.crot(color)
	-- rotate color
	return 255 - color % 255
end

function math.climit(color)
	return math.limit(color, 0, 255)
end

function drawObject(v, r, g, b)
  local lg = love.graphics
  if v.shape == 'rect' then
    local x, y, w, h = v.x, v.y, v.hw, v.hh
    local r = 90
    local g = 66
    local b = 34
    lg.setColor(r, g, b, 255)
    lg.rectangle("fill", x - w, y - h, w * 2, h * 2)
    --lg.setColor(math.climit(r-60), math.climit(g-60), math.climit(b-60), 255)
    --lg.rectangle("line", x - w, y - h, w * 2, h * 2)
    --lg.rectangle("line", x - w + 1, y - h + 1, w * 2 - 2, h * 2 - 2)
    -- DRAW COOL SHIT HERE
  elseif v.shape == 'circle' then
    local x, y, radius = v.x, v.y, v.r
    lg.setColor(r, g, b, 255)
    lg.circle("fill", x, y, radius, 32)
  end
end

function love.load()

	love.mouse.setVisible(false)
	
	--image = love.graphics.newImage("cake.jpg")
	
	love.graphics.setBackgroundColor(30,30,30)

	--Load 3rd party libraries
	--require("resources.libs.fizz.quad")
	require("fizz")
	fizz.maxVelocity = 1000
	fizz.gravity = 1500
	statics = {}
	dynamics = {}

	gui = require "resources.libs.quickie"


	gui.layer = {}
	
	--Load main files
	require("imageDatabase")
	--love.joystick = require('XInputLUA')
	--xpad = require('XPad')


	require("intro")
	require("UIcustoms")
	require("createFonts")
	require("input")
	require("title")
	require("levelEditor")
	require("tableSave")


	gui.group.default.size[1] = 150
	gui.group	.default.size[2] = 25
	gui.group.default.spacing = 5

end

local check1   = false
local check2   = false
local input	= {text = ""}
local slider   = {value = .5}
local slider2d = {value = {.5,.5}}


local ur = "stay"

function love.update(dt)
	

	--if love.keyboard.isDown("up") then
	--   num = num + 100 * dt -- this would increment num by 100 per second
	--end
	
	if game.isPaused then
		love.mouse.setGrab(false)
	else
		love.mouse.setGrab(true)
	end
	
	if not game.hasFocus and game.canTogglePause then
		game.isPaused = true
		return
	end

	if game.playercount then
		for i, p in pairs(game.players) do

			-- initiate movement variables
			if not p.maxMove then p.maxMove = 3500 end
			if not p.move then p.move = p.maxMove end

			-- reset player 'grounded' variable
			p.grounded = false

			-- delta must be in seconds
			-- not too large or there will be tunneling
			dt = math.min(dt, 0.032)
			
			fizz.update(dt)

			if p.jumptime then
				p.jumptime = p.jumptime + dt
			end
			-- horizontall speed
			p.maxMove = 2500
			p.hSpeed = 40
			if p.grounded == false then
				p.maxMove = 500
				if not p.ugt then p.ugt = 0 end
				p.ugt = p.ugt + 1
			end

			--Gives the player a little time after falling to press jump, 
			-- improves flow.
			if p.ugt and p.ugt>11 then
				if not p.jumpNum then p.jumpNum = 0 end
				p.jumpNum = p.jumpNum+1
			end

			
			-- vertical speed
			local jump = 10000
			local l = love.keyboard.isDown("left")
			local r = love.keyboard.isDown("right")
			local u = love.keyboard.isDown(" ")
			-- player horizontal velocity

			if p.grounded then
				p.ugt = 0
				p.hasJump = true
				p.jumpNum = 0
				p.downfall = false
			end


			--This is the "slow down" or "slide" at the end of running
			if (not l and not r) or (l and p.move>0) or (r and p.move<0) then
				p.move = p.move - p.move / (p.hSpeed/5)
			end
			
			--This accelerates the char if you haven't maxed out speed
			if l and p.move > - p.maxMove then
				p.move = p.move - p.hSpeed
			elseif r and p.move < p.maxMove then
				p.move = p.move + p.hSpeed
			end

			p.xv = p.xv + p.move*dt

			p.c = 1
			if u then
				-- keep track of jump time
				if p.hasJump then
					p.jumptime = dt
				end
				if p.jumptime and p.jumptime < 0.10 then
					--p.c = math.cos((p.jumptime/0.25*(math.pi/2))/(2*p.jumpNum))
					p.c = math.cos((p.jumptime/0.25*(math.pi/2))/2)

					if p.downfall then
						p.c = math.cos((p.jumptime/0.25*(math.pi/2))/2)
					end
					-- player vertical velocity
					p.yv = p.yv - jump*p.c*dt
				end
				if p.jumptime and p.yv <= 0 then
					p.downfall = true
				end
			end

			
		end
	end
		
	
	hook.Call("think", {dt})
	hook.Call("guiDraw", {dt})

end

hook.Add("keyPressed", "keypressjump", function() 
	

end)

function table.HasValue( t, v)
	for k,vl in pairs(t) do
		if vl == v then 
			return k
		end
	end
	return false
end

function love.focus(f)
	game.hasFocus = f
end


local cSize = 3
local circletracker = 1

function radianOverflow(radian)
	if radian < math.pi then return radian
		else return radian - math.pi*(radian/math.pi) end
end

local rate
local cSize
local scale = 4
local oneRad = math.pi/180
local distance = 4

function love.draw()
	local lg = love.graphics
	
	if not game.isPaused then

		for i, v in ipairs(statics) do
			drawObject(v, 127, 127, 255)
		end
		for i, v in ipairs(dynamics) do
			drawObject(v, 255, 127, 255)
		end
		--[[
		for i, v in ipairs(kinematics) do
			drawObject(v, 255, 127, 255)
		end]]
		lg.setColor(255, 255, 255, 255)
		lg.print("col checks:" .. fizz.cchecks, 0, 0)
		--lg.print("quad livecells:" .. quad.livecells, 0, 45)
		lg.print("objects:" .. quad.objects, 0, 15)
		local mem = collectgarbage('count')
		mem = math.ceil(mem)
		lg.print("memory:" .. mem, 0, 30)

		gui.core.draw()

		hook.Call("draw", {})

	end

	if game.isPaused then 
		local PausedSign = "GAME PAUSED"
		local Font = fontsTable.paused
		
			lg.setFont(Font)
			lg.setColor(255,255,255,255)
			lg.print(PausedSign, ScrW()/2-Font:getWidth(PausedSign)/2, ScrH()/4 - Font:getHeight(PausedSign)/2)
	end
	
	cSize = 2
	rate = 0.4
	circletracker = circletracker + rate

	if circletracker>360 then circletracker = 1 end

	local t = oneRad*circletracker

		lg.setColor(150,0,0,255)

		lg.circle("line", love.mouse.getX()-cSize+(cSize*distance*math.cos(t)) , love.mouse.getY()-cSize+(cSize*4*math.sin(t)), cSize,15)
		lg.circle("line", love.mouse.getX()-cSize+(cSize*distance*math.cos(t+oneRad*90)) , love.mouse.getY()-cSize+(cSize*4*math.sin(t+oneRad*90)), cSize,15)
		lg.circle("line", love.mouse.getX()-cSize+(cSize*distance*math.cos(t+oneRad*180)) , love.mouse.getY()-cSize+(cSize*4*math.sin(t+oneRad*180)), cSize,15)
		lg.circle("line", love.mouse.getX()-cSize+(cSize*distance*math.cos(t+oneRad*270)) , love.mouse.getY()-cSize+(cSize*4*math.sin(t+oneRad*270)), cSize,15)

	
	cSize = cSize + scale
		lg.circle("line", love.mouse.getX()-cSize+scale, love.mouse.getY()-cSize+scale, cSize,15)
	--	lg.print(Cursor, love.mouse.getX()-Font:getWidth(Cursor)/2, love.mouse.getY()-Font:getHeight(Cursor)/2)

end



function love.mousepressed(x, y, button)
	hook.Call("mousePressed", {x, y, button})
end

function love.mousereleased(x, y, button)
	hook.Call("mouseReleased", {x, y, button})
end

function love.keypressed(key, unicode)
	if game and game.players and game.players[1] and game.players[1].hasJump and key == " " then
		game.players[1].jumpNum = game.players[1].jumpNum + 1
	end
	hook.Call("keyPressed", {key, unicode})
end

function love.keyreleased(key, unicode)
	hook.Call("keyReleased", {key, unicode})
end

function love.quit()
	hook.Call("exit", {})
end